#include "exit.h"
#include "tick.h"

#undef TRACE_LEVEL
#undef TRACE_TITLE
#undef TRACE_TITLE
#define TRACE_LEVEL	TRACE_LEVEL_DEBUG
#define TRACE_NAME  TRACE_NAME_DISABLE
#define TRACE_TITLE "EXTIT"
#include "trace.h"


static void Config_IO_Input(GPIO_TypeDef *GPIOx, uint16_t Pin, GPIOMode_TypeDef mode);
static void EXTIT_Interrupt_Config(void);

/* EXTERN IN state.c */
// extern int CS3144_EVENT_MARK;
// extern uint32_t CS3144_TIME_MARK;
// extern int LASER_EVENT_MARK[3];
// extern uint32_t LASER_TIME_MARK[3];
// extern uint16_t CS3144_IO_VALUE;
// extern uint16_t LASER_IO_VALUE[3];

/*
** @ Init the EXT-Interrupt
**/
void EXTIT_Init() {
	Config_IO_Input(CSINT_GPIO, CSINT_PIN, GPIO_Mode_IPU);
	Config_IO_Input(LASER1_GPIO, LASER1_PIN, GPIO_Mode_IPU);
	Config_IO_Input(LASER2_GPIO, LASER2_PIN, GPIO_Mode_IPU);
	Config_IO_Input(LASER3_GPIO, LASER3_PIN, GPIO_Mode_IPU);
	
	/* CS3144 */
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14);
	
	/* LASER1 */
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource13);
	
	/* LASER2 */
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
	
	/* LASER3 */
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource15);
	
	/* Config the EXTIT interrupt */
	EXTIT_Interrupt_Config();
}

/*
** @ DeInit the EXT-Interrupt
**/
void EXTIT_DeInit() {
	EXTI_DeInit();
	
	Config_IO_Input(CSINT_GPIO, CSINT_PIN, GPIO_Mode_IN_FLOATING);
	Config_IO_Input(LASER1_GPIO, LASER1_PIN, GPIO_Mode_IN_FLOATING);
	Config_IO_Input(LASER2_GPIO, LASER2_PIN, GPIO_Mode_IN_FLOATING);
	Config_IO_Input(LASER3_GPIO, LASER3_PIN, GPIO_Mode_IN_FLOATING);
}

/*
** @ Get EXT-INT IO level
**/
int Get_EXTIO(EXTIT_Index_t index) {
	BitAction ret;
	
	switch (index) {
	case CS3144_INDEX:
		ret = GPIO_ReadInputDataBit(CSINT_GPIO, CSINT_PIN); 
	case LASER1_INDEX:
		ret = GPIO_ReadInputDataBit(LASER1_GPIO, LASER1_PIN);
	case LASER2_INDEX:
		ret = GPIO_ReadInputDataBit(LASER2_GPIO, LASER2_PIN);
	case LASER3_INDEX:
		ret = GPIO_ReadInputDataBit(LASER3_GPIO, LASER3_PIN);
	}
	if (ret == Bit_SET) {
		return 1;
	} else {
		return 0;
	}
}


static void Config_IO_Input(GPIO_TypeDef *GPIOx, uint16_t Pin, GPIOMode_TypeDef mode) {
	GPIO_InitTypeDef   GPIO_InitStructure;
	
	GPIO_InitStructure.GPIO_Mode = mode;
	GPIO_InitStructure.GPIO_Pin = Pin;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOx, &GPIO_InitStructure);
}


static void EXTIT_Interrupt_Config(void) {
	EXTI_InitTypeDef   EXTI_InitStructure;
	
	/* Configure EXTI1 line : CS3144 */
	EXTI_InitStructure.EXTI_Line = EXTI_Line14;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;  
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStructure);
	
	/* Configure EXTI1 line : LASER1 */
	EXTI_InitStructure.EXTI_Line = EXTI_Line13;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;  
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStructure);
	
	/* Configure EXTI0 line : LASER2 */
	EXTI_InitStructure.EXTI_Line = EXTI_Line0;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;  
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStructure);
	
	/* Configure EXTI0 line : LASER3 */
	EXTI_InitStructure.EXTI_Line = EXTI_Line15;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;  
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStructure);
}

// void EXTIT_CS3144_Callback(void) {
// 	//TRACE_DEBUG("CS3144 [%d]", get_tick_count());
// 	if (CS3144_EVENT_MARK == 0) {
// 		CS3144_TIME_MARK = get_tick_count();
// 		CS3144_IO_VALUE = Get_EXTIO(CS3144_INDEX);
// 		CS3144_EVENT_MARK = 1;
// 	}
// }

// void EXTIT_LASER1_Callback(void) {
// 	//TRACE_DEBUG("LASER1 [%d]", get_tick_count());
// 	if (LASER_EVENT_MARK[0] == 0) {
// 		LASER_TIME_MARK[0] = get_tick_count();
// 		LASER_IO_VALUE[0] = Get_EXTIO(LASER1_INDEX);
// 		LASER_EVENT_MARK[0] = 1;
// 	}
// }

// void EXTIT_LASER2_Callback(void) {
// 	//TRACE_DEBUG("LASER2 [%d]", get_tick_count());
// 	if (LASER_EVENT_MARK[1] == 0) {
// 		LASER_TIME_MARK[1] = get_tick_count();
// 		LASER_IO_VALUE[1] = Get_EXTIO(LASER2_INDEX);
// 		LASER_EVENT_MARK[1] = 1;
// 	}
// }

// void EXTIT_LASER3_Callback(void) {
// 	//TRACE_DEBUG("LASER3 [%d]", get_tick_count());
// 	if (LASER_EVENT_MARK[2] == 0) {
// 		LASER_TIME_MARK[2] = get_tick_count();
// 		LASER_IO_VALUE[2] = Get_EXTIO(LASER3_INDEX);
// 		LASER_EVENT_MARK[2] = 1;
// 	}
// }


// TEST ONLY ****** TEST ONLY ****** TEST ONLY ****** TEST ONLY ****** TEST ONLY ******
int EXTIT_Main() {
	EXTIT_Init();
	while(1);
}
